// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: GPL-3.0-only

package storage

import (
	"context"
	"fmt"

	"atomgit.com/openlinksaas-org/proto-gen-go.git/project_server_api"
	"gitcode.com/openseaotter/so_proto_gen_go.git/member_api"
	"gitcode.com/openseaotter/so_server/utils"
	"github.com/dgraph-io/badger/v4"
)

type RemoteMemberInfo struct {
	ProjectId         string
	MemberUserId      string
	MemberDisplayName string
	MemberLogoUri     string
	MemberIsAdmin     bool
}

func QueryMember(ctx context.Context, addr, accessToken string) (*RemoteMemberInfo, *member_api.MemberInfo, error) {
	conn, err := utils.ConnGrpcServer(addr)
	if err != nil {
		return nil, nil, err
	}
	defer conn.Close()

	client := project_server_api.NewProjectServerApiClient(conn)
	res, err := client.QueryByAccessToken(ctx, &project_server_api.QueryByAccessTokenRequest{
		Token: accessToken,
	})
	if err != nil {
		return nil, nil, err
	}
	if res.Code != project_server_api.QueryByAccessTokenResponse_CODE_OK {
		return nil, nil, fmt.Errorf("%s", res.ErrMsg)
	}

	remoteMember := &RemoteMemberInfo{
		ProjectId:         res.ProjectId,
		MemberUserId:      res.MemberUserId,
		MemberDisplayName: res.MemberDisplayName,
		MemberLogoUri:     res.MemberLogoUri,
		MemberIsAdmin:     res.MemberIsAdmin,
	}

	needUpdate := false
	localMember, err := MemberDao.Get(ctx, res.ProjectId, res.MemberUserId)
	if err != nil {
		if err != badger.ErrKeyNotFound {
			return nil, nil, err
		}
		needUpdate = true
	} else {
		if remoteMember.MemberDisplayName != localMember.MemberDisplayName || remoteMember.MemberLogoUri != localMember.MemberLogoUri {
			needUpdate = true
		}
	}

	if needUpdate {
		newMemberItem := &member_api.MemberInfo{
			MemberUserId:      remoteMember.MemberUserId,
			MemberDisplayName: remoteMember.MemberDisplayName,
			MemberLogoUri:     remoteMember.MemberLogoUri,
		}
		if localMember == nil {
			newMemberItem.Perm = &member_api.MemberPerm{
				ManageAuthSecret: res.MemberIsAdmin,
				ManageWatch:      res.MemberIsAdmin,
			}
		} else {
			newMemberItem.Perm = localMember.Perm
		}
		err = MemberDao.Set(ctx, res.ProjectId, newMemberItem)
		if err != nil {
			return nil, nil, err
		}
		localMember, err = MemberDao.Get(ctx, res.ProjectId, res.MemberUserId)
		if err != nil {
			return nil, nil, err
		}
	}
	return remoteMember, localMember, nil
}
